package cn.uyunsky.platform.service.impl;

import cn.uyunsky.platform.data.GridPageVO;
import cn.uyunsky.platform.data.UData;
import cn.uyunsky.platform.data.UDataTool;
import cn.uyunsky.platform.entity.impl.PlRole;
import cn.uyunsky.platform.entity.impl.PlUser;
import cn.uyunsky.platform.exception.PLException;
import cn.uyunsky.platform.jdbc.page.PageRequest;
import cn.uyunsky.platform.service.IServiceAbstract;
import cn.uyunsky.platform.util.PL;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.*;

/**
 * 实现平台用户的CRUD和维护操作
 * User: baiyh
 * Date: 13-6-15
 * Time: 下午3:45
 */
@Service(value = "PLUserService")
@Transactional
public class PLUserService extends IServiceAbstract {

    private static class OPTYPE {
        public static final String ADD = "ADD";
        public static final String UPD = "UPD";
        public static final String DEL = "DEL";
        public static final String STOP = "STOP"; // 停用
        public static final String START = "START"; // 启用
        public static final String GET = "GET";//根据rowid获取记录
        public static final String SEARCH = "SEARCH";
    }

    private HibernateTemplate hibernateTemplate;

    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }

    @Override
    public UData doService(UData data) throws PLException {
        String optype = (String) data.getBody().get("optype");
        String pluserid = null;
        if (OPTYPE.ADD.equals(optype)) {
            pluserid = this.addUser(data);
        } else if (OPTYPE.UPD.equals(optype)) {
            pluserid = this.updateUser(data);
        } else if (OPTYPE.DEL.equals(optype)) {
            pluserid = this.deleteUser(data);
        } else if (OPTYPE.STOP.equals(optype)) {
            pluserid = this.stopUser(data);
        } else if (OPTYPE.START.equals(optype)) {
            pluserid = this.startUser(data);
        } else if (OPTYPE.GET.equals(optype)) {
            return this.getUser(data);
        } else if (OPTYPE.SEARCH.equals(optype)) {
            return this.searchUser(data);
        } else {
            throw new PLException("9999");
        }

        return UDataTool.createOneUData("id", pluserid);
    }

    private UData getUser(UData data) {
        String id = (String) data.getBody().get("id");

        PlUser plUser = hibernateTemplate.load(PlUser.class, id);
        Map<String, Object> resBody = new HashMap<String, Object>();
        resBody.put("id", plUser.getId());
        resBody.put("userid", plUser.getUserid());
        resBody.put("username", plUser.getUsername());
        resBody.put("roleid", plUser.getRole().getId());
        resBody.put("rolename", plUser.getRole().getRoleDes());
        resBody.put("status", plUser.isStatus());
        resBody.put("password", plUser.getPassword());
        resBody.put("registerDate", plUser.getRegisterDate());

        return UDataTool.createSuccessResult(resBody);
    }


    private String startUser(UData data) {
        String pluserid = (String) data.getBody().get("id");
        PlUser user = hibernateTemplate.load(PlUser.class, pluserid);
        user.setStatus(true);
        return user.getId();
    }

    private String stopUser(UData data) {
        String pluserid = (String) data.getBody().get("id");
        PlUser user = hibernateTemplate.load(PlUser.class, pluserid);
        user.setStatus(false);
        return user.getId();
    }

    private String deleteUser(UData data) {
        String pluserid = (String) data.getBody().get("id");
        PlUser user = hibernateTemplate.load(PlUser.class, pluserid);
        hibernateTemplate.delete(user);
        return pluserid;
    }

    private String updateUser(UData data) {
        String json = data.getJson();
        PlUser user = PL.JSON.fromJSON(json, PlUser.class);

        PlUser pluser = hibernateTemplate.load(PlUser.class, user.getId());
        pluser.setUserid(user.getUserid());
        pluser.setUsername(user.getUsername());
        pluser.setPassword(PL.md5encode(user.getPassword()));
        pluser.setStatus(user.isStatus());

        String roleid = (String) data.getBody().get("roleid");
        PlRole plrole = hibernateTemplate.load(PlRole.class, roleid);
        pluser.setRole(plrole);

        return user.getId();
    }

    private String addUser(UData data) {
        String json = data.getJson();
        PlUser user = PL.JSON.fromJSON(json, PlUser.class);
        user.setCreateUserid(data.getHead().getUserid());
        user.setRegisterDate(new Timestamp(new Date().getTime()));
        user.setStatus(true);

        String password = user.getPassword();
        user.setPassword(PL.md5encode(password));

        String roleid = (String) data.getBody().get("roleid");
        PlRole plrole = hibernateTemplate.load(PlRole.class, roleid);
        user.setRole(plrole);

        String pluserid = (String) hibernateTemplate.save(user);
        return pluserid;
    }


    private UData searchUser(UData data) {
        final String parameter = (String) data.getBody().get("parameter");

        //组装sql
        StringBuilder hqltmp = new StringBuilder();
        hqltmp.append(" from PlUser t");
        if (!PL.isEmpty(parameter)) {
            hqltmp.append(" where t.userid like CONCAT('%', :parameter, '%')");
            hqltmp.append(" or t.username like CONCAT('%', :parameter, '%')");
        }
        final String hql = hqltmp.toString();
        final String totalhql = "select count(t) " + hql;
        logger.debug("hql:{}, \n totalhql:{}", hql, totalhql);

        final int[] page = PL.hibernateTemplateHelper.getPageParameter(data.getBody());

        List list = hibernateTemplate.executeFind(new HibernateCallback<Object>() {
            @Override
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(hql);
                query.setFirstResult(page[0]);
                query.setMaxResults(page[1]);
                if (!PL.isEmpty(parameter)) {
                    query.setParameter("parameter", parameter);
                }
                List list = query.list();

                //由于session仅在这里,因此需要这里转换结果bean
                List<Map<Object, Serializable>> gridList = new ArrayList<Map<Object, Serializable>>();

                for (int i = 0; i < list.size(); i++) {
                    PlUser plUser = (PlUser) list.get(i);
                    Map<Object, Serializable> record = new HashMap<Object, Serializable>();
                    record.put("id", plUser.getId());
                    record.put("userid", plUser.getUserid());
                    record.put("username", plUser.getUsername());
                    record.put("roleid", plUser.getRole().getId());
                    record.put("rolename", plUser.getRole().getRoleDes());
                    record.put("status", plUser.isStatus());
                    record.put("registerDate", plUser.getRegisterDate());

                    gridList.add(record);
                }
                return gridList;
            }
        });

        long total = 0;
        if (!PL.isEmpty(parameter)) {
            total = DataAccessUtils.longResult(hibernateTemplate.findByNamedParam(totalhql, "parameter", parameter));
        } else {
            total = DataAccessUtils.longResult(hibernateTemplate.find(totalhql));
        }
        GridPageVO vo = new GridPageVO(total, list);

        /*======================另一种方式=========================
        final String hql2 =
                //"select t.id, t.userid, t.username, t.registerDate, t.status, t.role.id, t.role.roleDes" +
                " from PlUser t" +
                        " where t.userid = :parameter" +
                        " or t.username like CONCAT('%', :parameter, '%')";

        PageRequest pageRequest = PageRequestFactory.bindPageRequest(new PLUserPageRequest(), data.getBody());
        Page pageRes = PL.hibernateTemplateHelper.pageQuery(hql2, pageRequest);
        GridPageVO vo = new GridPageVO(pageRes.getTotalCount(), pageRes.getResult());
        */

        //logger.debug("vo json:"+ JsonTool.toJSON(vo));
        return UDataTool.createOneUData("grid", vo);
    }


    public static class PLUserPageRequest extends PageRequest {

        private String parameter;

        public String getParameter() {
            return parameter;
        }

        public void setParameter(String parameter) {
            this.parameter = parameter;
        }
    }

}
